package services

import (
	"backend/form"
	"backend/log"
	"backend/models"
	"backend/utils"
	"fmt"

	"go.uber.org/zap"
)

func GetMenuTree(role_id []uint, supper bool) ([]*form.MenuTree, error) {

	//根据角色ID过滤权限是否需要勾选状态
	var roles []models.Role

	if supper {
		if err := utils.DB.Preload("Permissions").Find(&roles).Error; err != nil {
			return nil, err
		}
	} else {
		// 预加载角色的 Permissions
		if err := utils.DB.Preload("Permissions").Where("id in ?", role_id).Find(&roles).Error; err != nil {
			return nil, err
		}
	}

	// 获取角色的所有权限ID

	permissionIDs := make(map[uint]bool)
	for _, role := range roles {
		for _, permission := range role.Permissions {
			permissionIDs[permission.ID] = true
		}
	}

	//下面是返回全部权限树的，是否需要勾选，则是根据角色ID来判断的
	var menus []models.Menu

	// 加载所有菜单及其子菜单和权限
	err := utils.DB.Preload("Children.Permissions").Preload("Permissions").Find(&menus).Error
	if err != nil {
		log.Logger.Error("Failed to get menus", zap.Error(err))
		return nil, err
	}

	// 建立 Menu ID 到 MenuTree 的映射
	menuMap := make(map[uint]*form.MenuTree, len(menus))
	for _, menu := range menus {
		menuMap[menu.ID] = &form.MenuTree{
			Id:       fmt.Sprintf("menu_%d", menu.ID),
			Label:    menu.Name, // 使用 Label 适应前端需求
			Path:     menu.Path,
			Icon:     menu.Icon,
			OrderNum: menu.OrderNum,
			Level:    menu.Level,
			Show:     false,
		}

	}

	// 构建树形结构并将权限转为 children
	var menuTrees []*form.MenuTree
	for _, menu := range menus {
		// 转换权限为子节点
		for _, perm := range menu.Permissions {
			permChild := &form.MenuTree{
				Id:          fmt.Sprintf("perm_%d", perm.ID),
				Label:       perm.Name,
				Level:       menu.Level + 1, // 权限作为下一层级
				Permissions: []uint{perm.ID},
				Path:        perm.Path,
				Action:      perm.Action,
				Checked:     permissionIDs[perm.ID],
			}
			//如果子节点有任意权限，则父节点需要显示
			if _, ok := permissionIDs[perm.ID]; ok {
				menuMap[menu.ID].Show = true
				permChild.Show = true
			}

			menuMap[menu.ID].Children = append(menuMap[menu.ID].Children, permChild)
			// menuMap[menu.ID].Permissions = append(menuMap[menu.ID].Permissions, perm.Action)
		}

		// 构建菜单树
		if menu.ParentID != nil {
			parent, exists := menuMap[*menu.ParentID]
			if exists {
				parent.Children = append(parent.Children, menuMap[menu.ID])
				// 子菜单有显示时，父菜单也显示
				if menuMap[menu.ID].Show {
					parent.Show = true
				}
			}
		} else {
			menuTrees = append(menuTrees, menuMap[menu.ID])
		}
	}

	return menuTrees, nil
}
